home *** CD-ROM | disk | FTP | other *** search
- #include "term.h"
- #include <osbind.h>
- #include <mintbind.h>
- #include <keycodes.h>
- #include <process.h>
- #include <signal.h>
- #include <sgtty.h>
-
- /* key that gets us out of VT52 -- ^G, for now */
- #define QUITKEY '\007'
- extern void normal_putch(), escy_putch();
-
- int kidpid; /* child's process id */
- int kidfd; /* child's file descriptor */
- int savex, savey; /* saved x, y coordinates */
- void (*state)();
-
- /*
- * clrfrom(x1, y1, x2, y2): clear screen from position (x1,y1) to
- * position (x2, y2) inclusive. It is assumed that y2 >= y1.
- */
-
- void
- clrfrom(x1, y1, x2, y2)
- int x1,y1,x2,y2;
- {
- }
-
- void
- ignore()
- {
- state = normal_putch;
- }
-
- /*
- * putesc(v, c): handle the control sequence ESC c
- */
-
- #define gotoxy(x, y) m_move(x, y)
-
- void
- putesc(c)
- int c;
- {
- int cx, cy;
-
- switch (c) {
- case 'A': /* cursor up */
- m_up(10); /* BUG -- this scrolls; it shouldn't */
- break;
- case 'B': /* cursor down */
- m_down(10); /* BUG -- this scrolls; it shouldn't */
- break;
- case 'C': /* cursor right */
- m_right(10);
- break;
- case 'D': /* cursor left */
- m_left(10);
- break;
- case 'E': /* clear home */
- m_clear();
- break;
- case 'H': /* cursor home */
- gotoxy(0, 0);
- break;
- case 'I': /* cursor up, insert line */
- m_up(10);
- break;
- case 'J': /* clear below cursor */
- m_cleareos();
- break;
- case 'K': /* clear remainder of line */
- m_cleareol();
- break;
- case 'L': /* insert a line */
- m_addline();
- break;
- case 'M': /* delete line */
- m_deleteline();
- break;
- case 'Y':
- state = escy_putch;
- return; /* YES, this should be 'return' */
- case 'b': /* set foreground color */
- case 'c': /* set background color */
- state = ignore;
- return;
- case 'd': /* clear to cursor position */
- get_cursor(&cx, &cy);
- clrfrom(0, 0, cx, cy);
- break;
- case 'e': /* enable cursor */
- m_setcursor(CS_BLOCK);
- break;
- case 'f': /* cursor off */
- m_setcursor(CS_INVIS);
- break;
- case 'j': /* save cursor position */
- get_cursor(&savex, &savey);
- break;
- case 'k': /* restore saved position */
- gotoxy(savex, savey);
- break;
- case 'l': /* clear line */
- get_cursor(&cx, &cy);
- gotoxy(0, cy);
- m_cleareol();
- break;
- case 'o': /* clear from start of line to cursor */
- get_cursor(&cx, &cy);
- clrfrom(0, cy, cx, cy);
- break;
- case 'p': /* reverse video on */
- m_standout();
- break;
- case 'q': /* reverse video off */
- m_standend();
- break;
- case 'v': /* wrap on */
- m_clearmode(M_NOWRAP);
- break;
- case 'w':
- m_setmode(M_NOWRAP);
- break;
- }
- state = normal_putch;
- }
-
- /*
- * escy1_putch(c): for when an ESC Y + char has been seen
- */
-
- int escy1;
-
- void
- escy1_putch(c)
- int c;
- {
- gotoxy(c - ' ', escy1 - ' ');
- state = normal_putch;
- }
-
- /*
- * escy_putch(v, c): for when an ESC Y has been seen
- */
-
- void
- escy_putch(c)
- int c;
- {
- escy1 = c;
- state = escy1_putch;
- }
-
- /*
- * normal_putch(c): put character 'c' on screen. This is the default
- * for when no escape, etc. is active
- */
-
- void
- normal_putch(c)
- int c;
- {
- if (c == '\033')
- state = putesc;
- else
- m_putchar(c);
- }
-
- static inline
- void
- put_ch(c)
- int c;
- {
- (*state)(c);
- }
-
- int
- run(shell, argv)
- char *shell, **argv;
- {
- int fd, oldtty;
- long pid;
- static char pty[] = "Q:\\VT52@";
-
- /* create our handle */
- pid = 0;
- do {
- pty[7]++; pid++;
- fd = Fcreate(pty, FA_SYSTEM|FA_HIDDEN);
- } while (fd < 0 && pid < 8);
-
- if (fd < 0) {
- printf("couldn't create a pty\n");
- quit(2);
- }
- kidfd = fd;
-
- /* now create the child's handle */
- fd = Fopen(pty, 2);
-
- oldtty = Fdup(-1);
- if (oldtty < 0) {
- Cconws("couldn't dup control terminal!\r\n");
- quit(2);
- }
- Fforce(-1, fd); /* set up new control terminal */
- Fforce(0, fd);
- Fforce(1, fd);
- Fforce(2, fd);
- pid = spawnvp(P_NOWAIT, shell, argv); /* spawn child in background */
- Fforce(-1, oldtty);
- Fforce(0, oldtty);
- Fforce(1, oldtty);
- Fforce(2, oldtty);
- if (pid < 0) {
- Cconws("couldn't run ");
- Cconws(shell);
- Cconws("\r\n");
- quit((int)pid);
- }
- Psetpgrp((int)pid, (int)pid); /* set the child's process group */
- Fcntl(fd, &pid, TIOCSPGRP); /* set the terminal process group */
- Fclose(fd);
-
- kidpid = pid;
- return kidfd;
- }
-
- int
- quit(x)
- int x;
- {
- m_setnoraw();
- if (kidpid)
- Pkill((int)-kidpid, SIGHUP);
- Pterm(x);
- }
-
- #define INBUFSIZ 256
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int fd;
- long s, c;
- long reads, fdmask;
- unsigned char cbuf[INBUFSIZ], *cb;
- char *shell, *getenv();
- struct sgttyb sg;
-
- if (argc == 3 && !strcmp(argv[1], "-f")) {
- fd = Fopen(argv[2], 2);
- if (fd < 0) {
- perror(argv[2]);
- exit(1);
- }
- s = Pgetpgrp();
- Fcntl(fd, &s, TIOCSPGRP);
- Fcntl(fd, &sg, TIOCGETP);
- sg.sg_flags = RAW;
- Fcntl(fd, &sg, TIOCSETP);
- }
- else {
- if (argv[1]) {
- argv++;
- shell = argv[0];
- }
- else {
- shell = getenv("SHELL");
- if (!shell) shell="init.prg";
- argv[0] = shell;
- argv[1] = 0;
- }
- fd = run(shell, argv);
- }
-
- m_setup(0);
-
- m_size(80, 25);
- m_clear();
- m_setraw();
- m_setmode(M_NOBUCKEY);
-
- state = normal_putch;
-
- fdmask = 1L << fd;
-
- for(;;) {
- reads = 1 | fdmask;
- Fselect(0, &reads, 0L, 0L);
-
- if (reads & fdmask) {
- s = Finstat(fd);
- if (s > 0) {
- if (s > INBUFSIZ) s = INBUFSIZ;
- cb = cbuf;
- s = Fread(fd, s, cb);
- while (s-- > 0)
- put_ch(*cb++);
- m_flush();
- }
- else if (s < 0) {
- Cconws("Child exited??\r\n");
- quit((int)s);
- }
- }
- if (reads & 1) {
- c = Fgetchar(0, 0);
- if ( (c & 0xff) == QUITKEY )
- quit(0);
- Fputchar(fd, c, 0);
- }
- }
- }
-